package com.gobang.game;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.gobang.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;

import java.io.IOException;
import java.util.LinkedList;
import java.util.Queue;
@Component
//创建三个等级的队列,操作用户从对应等级队列中加入或者删除
public class Matcher {
    private Queue<User> nomalQueue = new LinkedList<>();
    private Queue<User> highQueue = new LinkedList<>();
    private Queue<User> veryHighQueue = new LinkedList<>();
    @Autowired
    private OnlineUserManager onlineUserManager;

    private ObjectMapper objectMapper = new ObjectMapper();
    @Autowired
    private RoomManager roomManager;
    //操作匹配队列的方法
    //把玩家放到匹配队列中
    public void add(User user){
        if(user.getScore()<2000){
            synchronized (nomalQueue){
                nomalQueue.offer(user);
                nomalQueue.notify();
            }
            System.out.println("把玩家"+user.getUsername()+"加入到nomalQueue队列中！");
        }else if(user.getScore()<3000){
            synchronized (highQueue) {
                highQueue.offer(user);
                highQueue.notify();
            }
            System.out.println("把玩家"+user.getUsername()+"加入到higeQueue队列中！");
        }else {
            synchronized (veryHighQueue){
                veryHighQueue.offer(user);
                veryHighQueue.notify();
            }
            System.out.println("把玩家"+user.getUsername()+"加入到veryHighQueue队列中！");
        }
    }
    //当玩家点击停止匹配，就需要玩家把匹配队列中删除
    public void remove(User user){
        if(user.getScore()<2000){
            synchronized (nomalQueue) {
                nomalQueue.remove(user);
                nomalQueue.notify();
            }
            System.out.println("把玩家"+user.getUsername()+"从nomalQueue队列中删除！");
        }else if(user.getScore()<3000){
            synchronized (highQueue){
                highQueue.remove(user);
                highQueue.notify();
            }

            System.out.println("把玩家"+user.getUsername()+"从higeQueue队列中删除！");
        }else {
            synchronized (veryHighQueue){
                veryHighQueue.remove(user);
                veryHighQueue.notify();
            }
        }
    }
    public Matcher(){
        //创建三个线程，分别针对这三个匹配队列，进行操作
        Thread t1 = new Thread(){
            @Override
            public void run(){
                //扫描normalQueue
                while(true){
                    handlerMatch(nomalQueue);
                }
            }
        };
        t1.start();
        Thread t2 = new Thread(){
            @Override
            public void run(){
                //扫描nhigeQueue
                while(true){
                    handlerMatch(highQueue);
                }
            }
        };
        t2.start();
        Thread t3 = new Thread(){
            @Override
            public void run(){
                //扫描veryHighQueue
                while(true){
                    handlerMatch(veryHighQueue);
                }
            }
        };
        t3.start();
    }
    //处理队列中的两两配对
    private void handlerMatch(Queue<User> matchQueue) {
        synchronized (matchQueue) {
            try {
                //1.如果当前等待队列中的玩家数量不到2个，直接退出方法，等待下一轮
                while (matchQueue.size() < 2) {
                    matchQueue.wait();
                }
                //2.玩家数量大于2，则从队列中取出两个玩家
                User player1 = matchQueue.poll();
                User player2 = matchQueue.poll();
                System.out.println("匹配出两个玩家:" + player1.getUsername() + "," + player2.getUsername());
                //获取到玩家的websocket会话，获取到会话的目的是为了告诉玩家，你排到了
                WebSocketSession session1 = onlineUserManager.getFromGameHall(player1.getUserId());
                WebSocketSession session2 = onlineUserManager.getFromGameHall(player2.getUserId());
                if (session1 == null) {
                    // 如果玩家1 下线, 则把玩家2 放回匹配队列
                    matchQueue.remove(player2);
                    return;
                }
                if (session2 == null) {
                    // 如果玩家1 下线, 则把玩家2 放回匹配队列
                    matchQueue.remove(player1);
                    return;
                }
                if (session2 == session1) {
                    // 如果得到的两个 session 相同, 说明是同⼀个玩家两次进⼊匹配队列
                    // 例如玩家点击开始匹配后, 刷新⻚⾯, 重新再点开始匹配
                    // 此时也把玩家放回匹配队列
                    matchQueue.remove(player1);
                    return;
                }
                //3.将两个玩家加入到游戏房间中
                Room room = new Room();

                // Room文件中有两个user1user2，还没有与当前的player1，player2建立联系
                roomManager.add(room, player1.getUserId(), player2.getUserId());
                //4.给玩家1发送响应数据
                MatchResponse response1 = new MatchResponse();
                response1.setOk(true);
                response1.setMessage("matchSuccess");
                session1.sendMessage(new TextMessage(objectMapper.writeValueAsString(response1)));
                //5.给玩家2发送响应数据
                MatchResponse response2 = new MatchResponse();
                response2.setOk(true);
                response2.setMessage("matchSuccess");
                session2.sendMessage(new TextMessage(objectMapper.writeValueAsString(response2)));
            } catch (IOException e) {
                e.printStackTrace();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
